import numpy as np
import math
import cv2 as cv
from scipy import signal
import random

def mixImage(image1, image2, scale=0.6):
	height1, width1 = image1.shape[:2]
	height2, width2 = image2.shape[:2]
	crop_size = (min(width1, width2), min(height1, height2))
	image1 = cv.resize(image1, crop_size, interpolation=cv.INTER_AREA)
	image2 = cv.resize(image2, crop_size, interpolation=cv.INTER_AREA)
	mix_image = cv.addWeighted(image1, scale, image2, 1-scale, 0)
	return mix_image


def creatLoGKernel(sigma, kSize):  #构建LOG算子
	winH = winW = kSize     #LOG算子的宽和高，两者都为奇数
	logKernel = np.zeros([kSize, kSize], np.float32)
	sigmaSquare = pow(sigma, 2.0)
	centerH = (winH - 1) / 2
	centerW = (winW - 1) / 2
	for r in range(winH):
		for c in range(winW):
			norm2 = pow(r - centerH, 2.0) + pow(c - centerW, 2.0)
			logKernel[r][c] = 1.0 / sigmaSquare * (norm2 / sigmaSquare - 2) * math.exp(-norm2 / (2 * sigmaSquare))
	return logKernel

def LoG(image, sigma, kSize, _boundary='fill', _fillValue=0):
	loGKernel = creatLoGKernel(sigma, kSize)
	#图像与卷积核卷积
	img_conv_log = signal.convolve2d(image, loGKernel, 'same', boundary=_boundary)
	return img_conv_log

def edge_binary(img):
	edge = np.copy(img)
	edge[edge >= 0] = 0
	edge[edge < 0] = 255
	edge = edge.astype(np.uint8)
	return edge

def getDraft(image, kSize):
	img = LoG(image, 2, kSize, 'symm')
	img = edge_binary(img)
	return img

#自适应直方图均衡化
def equalizeImage(img):
	(x, y) = img.shape
	size = 0
	if(x < y):
		size = int(x / 100)
	else:
		size = int(y / 100)
	clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(size, size))
	image = clahe.apply(img)
	return image

def getSketch(image, kSize, weight, isEqual):
	#iamge是图像数据，kSize越大细节越丰富，weight是灰度图像的权重，weight越大笔触越细腻
	#isEqual选择是否进行直方图均衡化
	gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
	if isEqual == True:
		gray = equalizeImage(gray)
	draft = getDraft(gray, kSize)
	sketch = (1 - weight) * draft + weight * gray
	return sketch

if __name__ == '__main__':
    imgInput_FileName = "demo5.jpg"
    imgMix_FileName = "demo4.jpg"
    imgOutput_FileName = imgInput_FileName.split(".")[0] + '_MixSketch.' + imgInput_FileName.split(".")[1]
    image1 = cv.imread(imgInput_FileName)
    image2 = cv.imread(imgMix_FileName)
    # 先混合，后素描
    print("图片混合中。。。", flush=True)
    image = mixImage(image1, image2, 0.5)
    print("素描生成中。。。", flush=True)
    out = getSketch(image, 13, 0.2, True)

    # 先素描，后混合
    # out1 = getSketch(image1, 13, 0.2, True)
    # out2 = getSketch(image2, 10, 0.2, True)
    # out = mixImage(out1, out2, 0.4)

    cv.imwrite(imgOutput_FileName, out)
    print(imgOutput_FileName + " is saved")
